<?php

namespace App\Http\Controllers\Api;

use App\Jobs\Shop\ShopOrderDeliverInfoManage;
use App\Lib\WeApp\WeApp;
use App\Models\Bureau\WxBureau;
use App\Models\Bureau\WxBureauGroup;
use App\Models\Bureau\WxClub;
use App\Models\Bureau\WxClubTeam;
use App\Models\Shop\WxShopContact;
use App\Models\Shop\WxShopGoods;
use App\Models\Shop\WxShopOrderCoupon;
use App\Models\Used\WxUsedGood;
use App\Wen\Utils\ApiUtils;
use App\Wen\Utils\GatewayUtils;
use App\Wen\Utils\Settings;
use App\Wen\Utils\ShopUtils;
use App\Wen\Utils\UserUtils;
use App\Wen\Utils\Utils;
use App\Wen\WeixinPay\WeixinPay;
use App\Http\Controllers\Api\Traits\PayTrait;
use App\Models\Shop\WxShopAddress;
use App\Models\Shop\WxShopCart;
use App\Models\Shop\WxShopGoodsProduct;
use App\Models\Shop\WxShopOrder;
use App\Models\Shop\WxShopOrderAfter;
use App\Models\Shop\WxShopOrderGoods;
use App\Models\User\WxUser;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;


class ShopOrderController extends BaseController
{
    use PayTrait;

    /**
     * 小程序SHOP下单地址
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function order(Request $request)
    {
        // todo
//        if(env('APP_URL') == 'https://mini.minisns.cn'){
//            return $this->fail(700003, [], '暂时请私下和群主联系');
//        }
        $uid = $request->uid;
        $r = $this->_create_order($request);
        if($r['code'] != 200){
            return $this->fail($r['code'], _array_key($r, 'data', []), $r['msg']);
        }

        //支付需要资料
        $openid = WxUser::where('id', $uid)->value('weixin_openid');
        $appid = Settings::get('app_id');
        $mch_id = Settings::get('mch_id');
        $key = Settings::get('mch_secret');
        $out_trade_no = $r['orderSn'];
        $body = Settings::get('app_title') . 'SHOP购物';
        $total_fee = $r['order_amount'];

        if(_empty_($openid)){
            return $this->fail(200043, [
                'title' => '未绑定微信',
                'content' => '还没有获取到您的小程序openId，无法拉起支付',
                'confirmText' => '去绑定',
                'target_type' => 6,
                'target_id' => '/pagesA/mine/editmine/accountbind'
            ], '未绑定微信');
        }

        return $this->payHandler($uid, 'wxpay', 'mini', $total_fee, $body, $out_trade_no, 2);

//        // 发起支付
//        $payObject = new WeixinPay($appid, $openid, $mch_id, $key, $out_trade_no, $body, $total_fee);
//        $pay_result = $payObject->pay();
//        if(_array_key($pay_result, 'return_code', '') == 'FAIL'){
//            return $this->fail(200014, [], $pay_result['return_msg']);
//        }else{
//            return $this->success($pay_result);
//        }
    }

    /** app商品统一下单地址
     * @param Request $request
     */
    public function orderForApp(Request $request){
        if(!in_array($request->provider, ['wxpay', 'alipay'])){
            return $this->fail(200004, ['msg'=>'provider参数仅支持wxpay/alipay']);
        }

        if(!in_array($request->pay_type, ['app', 'h5', 'yi', 'code', 'code_pc'])){
            return $this->fail(200004, ['msg'=>'pay_type参数仅支持app/h5/yi/code']);
        }

        $uid = $request->uid;
        $r = $this->_create_order($request);
        if($r['code'] != 200){
            return $this->fail($r['code'], _array_key($r, 'data', []), $r['msg']);
        }

        // 共同的资料
        $total_fee = $r['order_amount'];
        $body = Settings::get('app_title') . 'SHOP购物';
        $out_trade_no = $r['orderSn'];

        $pay_type = $request->pay_type;
        global $__MINI_GLOBAL_DEVICE__;
        if($__MINI_GLOBAL_DEVICE__ == 'h5' && _empty_default_($request->h5_browser, '') == 'wxclient'){
            $pay_type = 'mp';
        }

        return $this->payHandler($uid, $request->provider, $pay_type, $total_fee, $body, $out_trade_no, 2);
    }

    private function _create_order(Request $request){
        DB::beginTransaction();
        try {
            $r = ['code'=>0,'msg'=>'', 'orderSn'=>'', 'order_amount'=>0, 'orderId'=>0];
            $uid = $request->uid;
            $aid = $request->aid;
            $user_remark = $request->user_remark;

            $goods_amount = $request->goods_amount;
            $discounts_amount = $request->discounts_amount;
            $order_amount = $request->order_amount;
            $order_goods = $request->order_goods;
            $random_str_ = _empty_default_($request->random_str_, '');

            // 用于检验程序
            $buy_user = WxUser::where('id', $uid)->first();
            if (_empty_($buy_user) || _empty_($order_goods)) {
                DB::rollBack();
                $r['code'] = 200001;
                return $r;
            }
            $is_vip = $buy_user->is_member;
            $acculate_amount = 0;
            $acculate_vip_amount = 0;

            $seller_user_id = null;
            // 0:电商 6：二手 7: 组局
            $order_from = 0;
            $contact_id = 0;
            $order_goods_id = [];
            $goods_type_arr = [];

            foreach ($order_goods as $order_good){
                $goods_type_arr[] = $order_good['goods_type'];
                if($order_good['goods_type'] == 6){
                    // 闲置
                    $the_used_good = WxUsedGood::where('id', $order_good['goods_id'])->where('status', 1)->first();
                    if($the_used_good){

                        $order_from = 6;
                        $seller_user_id = $the_used_good->user_id;
                        $order_goods_id[] = $the_used_good->id;

                        if($the_used_good->price != $order_good['price']){
                            DB::rollBack();
                            $r['code'] = 200004;
                            $r['msg'] = '参数1检验失败，疑似参数被纂改';
                            return $r;
                        }else{
                            $acculate_amount += ($the_used_good->price * 1);
                            $acculate_vip_amount += ($the_used_good->price * 1);
                        }
                    }else{
                        DB::rollBack();
                        $r['code'] = 200003;
                        $r['msg'] = '订单中存在已售出的闲置商品';
                        return $r;
                    }

                }else if($order_good['goods_type'] == 7){
                    $the_bureau_good = WxBureau::where('id', $order_good['goods_id'])->where('status', 1)->first();
                    $the_club_team = WxClubTeam::find($order_good['product_id']);
                    if(!_empty_($the_bureau_good) && !_empty_($the_club_team)){
                        $the_bureau_group = WxBureauGroup::find($the_club_team->group_id);
                        if(_empty_($the_bureau_group)){
                            DB::rollBack();
                            $r['code'] = 200003;
                            $r['msg'] = '订单中指定的组局分组不存在';
                            return $r;
                        }
                        $order_from = 7;
                        $seller_user_id = $the_bureau_good->user_id;
                        $order_goods_id[] = $the_bureau_good->id;

                        if($the_bureau_good->type == 2){
                            DB::rollBack();
                            $r['code'] = 200003;
                            $r['msg'] = '暂不能处理战队比赛';
                            return $r;
                        }

                        // 有没有席位
                        $members_arr = $the_club_team->members;
                        if(count($members_arr) >= $the_club_team->members_limit){
                            DB::rollBack();
                            // todo: 这里有点粗糙，还需要检查支付中的订单
                            $r['code'] = 200004;
                            $r['msg'] = '已满员';
                            return $r;
                        }

                        // 检验性别
                        if($the_bureau_group->signup_gender > 0){
                            if($the_bureau_group->signup_gender == 1){
                                if($buy_user->gender != 1){
                                    DB::rollBack();
                                    $r['code'] = 200004;
                                    $r['msg'] = '仅限男性参加';
                                    return $r;
                                }
                            }else if($the_bureau_group->signup_gender == 2){
                                if($buy_user->gender != 2){
                                    DB::rollBack();
                                    $r['code'] = 200004;
                                    $r['msg'] = '仅限女性参加';
                                    return $r;
                                }
                            }
                        }

                        if($the_bureau_group->is_real_name == 1){
                            if(_empty_($buy_user->real_name)){
                                DB::rollBack();
                                $r['code'] = 200043;
                                $r['msg'] = '需实名认证';
                                $r['data'] = [
                                    'title' => '未实名认证',
                                    'content' => '您还没有实名认证，是否前往认证',
                                    'confirmText' => '去认证',
                                    'target_type' => 6,
                                    'target_id' => '/pagesA/mine/realname/realname'
                                ];
                                return $r;
                            }
                        }


                        if($the_bureau_group->cost_per_person != $order_good['price']){
                            DB::rollBack();
                            $r['code'] = 200004;
                            $r['msg'] = '参数1检验失败，疑似参数被纂改';
                            return $r;
                        }else{
                            $acculate_amount += ($the_bureau_group->cost_per_person * 1);
                            $acculate_vip_amount += ($the_bureau_group->cost_per_person * 1);
                            $contact_id = WxShopContact::where('club_id', $the_bureau_good->club_id)->value('id');
                        }
                    }else{
                        DB::rollBack();
                        $r['code'] = 200003;
                        $r['msg'] = '订单中存在非正常状态的闲置组局';
                        return $r;
                    }
                }else {
                    $the_product = WxShopGoodsProduct::where([['id', '=', $order_good['product_id']], ['goods_id', '=', $order_good['goods_id']], ['state', '=', 0]])->first();
                    if ($the_product) {
                        if($the_product['stock'] < 1){
                            DB::rollBack();
                            $r['code'] = 200004;
                            $r['msg'] = '规格库存不足';
                            return $r;
                        }
                        if($order_good['goods_type'] == 5){
                            $WxShopGoods = WxShopGoods::where('id', $the_product->goods_id)->first();
                            $contact_id = $WxShopGoods->contact_id;
                        }
                        if ($the_product->price != $order_good['price'] || $the_product->vip_price != $order_good['vip_price']) {
                            DB::rollBack();
                            $r['code'] = 200004;
                            $r['msg'] = '参数1检验失败，疑似参数被纂改';
                            return $r;
                        } else {
                            $order_goods_id[] = $the_product->goods_id;
                            $product_seller = WxShopGoods::where('id', $the_product->goods_id)->value('user_id');
                            if(_empty_($seller_user_id)){
                                $seller_user_id = $product_seller;
                            }else{
                                if($seller_user_id == $product_seller){

                                }else{
                                    $seller_user_id = null;
                                }
                            }
                            $acculate_amount += ($the_product->price * $order_good['num']);
                            $acculate_vip_amount += ($the_product->vip_price * $order_good['num']);
                        }
                    } else {
                        DB::rollBack();
                        $r['code'] = 200003;
                        return $r;
                    }
                }
            }

            if(in_array(2, $goods_type_arr) || in_array(3, $goods_type_arr)  || in_array(4, $goods_type_arr)){
                if(count(array_unique($goods_type_arr)) > 1){
                    DB::rollBack();
                    $r['code'] = 200004;
                    $r['msg'] = '虚拟，卡密商品不能和其他商品一起购买';
                    return $r;
                }
            }


            $acculate_order_amount = $is_vip ? $acculate_vip_amount : $acculate_amount;
            if(_abs($acculate_order_amount - $order_amount) >= 0.5 || _abs(($acculate_amount - $acculate_order_amount) - $discounts_amount) >= 0.5){
                DB::rollBack();
                $r['code'] = 200004;
                $r['msg'] = '参数2检验失败，疑似参数被纂改';
                return $r;
            }

            // 纠正前端数据
            $acculate_amount = round($acculate_amount, 2);
            $acculate_vip_amount = round($acculate_vip_amount, 2);
            $goods_amount = $acculate_amount;
            $discounts_amount = $is_vip ? round($acculate_amount - $acculate_vip_amount, 2) : 0;
            $order_amount = $is_vip ? $acculate_vip_amount : $acculate_amount;

            $orderSn = Utils::getSn(1);//生成订单号

            if($contact_id > 0 && _empty_($aid)){
                $addsinfo = [
                    'id' => 0,
                    'name' => '',
                    'mobile' => '',
                    'province' => '',
                    'city' => '',
                    'county' => '',
                    'adds' => '',
                ];
            }else{
                $addsinfo = WxShopAddress::where('user_id', $uid)->where('id', $aid)->first();//获取配送地址
                if(!$addsinfo){
                    DB::rollBack();
                    $r['code'] = 800003;
                    return $r;
                }
            }


            //生成SHOP订单
            $order_model = new WxShopOrder();
            $order_model->user_id = $uid;
            $order_model->order_id = $orderSn;//订单号
            $order_model->goods_amount = $goods_amount;//商品总价
            $order_model->discounts_amount = $discounts_amount;//优惠金额
            $order_model->order_amount = $order_amount;//订单总额
            $order_model->adds_id = $addsinfo['id'];//收货地址id
            $order_model->adds_name = $addsinfo['name'];//收货人姓名
            $order_model->adds_mobile = $addsinfo['mobile'];//收货人电话
            $order_model->address = $addsinfo['province'] . $addsinfo['city'] . $addsinfo['county'] . $addsinfo['adds'];//收货详细地址
            $order_model->contact_id = $contact_id;
            $order_model->user_remark = $user_remark;//用户备注
            $order_model->pay_status = 1;//支付状态 1=未付款 2=已付款 3=已退款
            $order_model->status = 0;//发货状态 0=正常 1=未发货 2=已发货 3=确认收货 4=已退货 5=取消
            $order_model->order_from = $order_from;
            $order_model->order_goods_id = $order_goods_id;
            if($seller_user_id > 0){
                // todo: 多商户这里需要拆订单
                $order_model->seller_user_id = $seller_user_id;
            }
            $order_model->save();

            $orderId = $order_model->id;//获取订单id


            //
            $_goods_amount = 0;
            $_order_amount = 0;

            //批量添加订单商品
            $orderGoods = [];
            foreach ($order_goods as $k => $v) {
                if($v['goods_type'] == 6){
                    $the_used_good = WxUsedGood::where('id', $v['goods_id'])->where('status', 1)->first();
                    if ($the_used_good) {
                        // 临时暂用
                        WxUsedGood::where('id', $v['goods_id'])->where('status', 1)->update(['status' => 7]);

                        if($the_used_good->image_urls){
                            $the_used_good->pic = _array_key($the_used_good->image_urls[0], 'url', '') . '';
                        }

                        $created_at = date('Y-m-d H:i:s', time());
                        $good_servers = [2];
                        $refund_deadline = Carbon::now()->addDays(7);
                        if(in_array(1, $good_servers)){
                            $refund_deadline = Carbon::now();
                            $created_at = $refund_deadline;
                        }

                        $recharge = $the_used_good->price * 1;
                        $_order_amount += $recharge;
                        $_goods_amount += $the_used_good->price * 1;



                        $orderGoods[$k]['pic'] = $the_used_good->pic;
                        $orderGoods[$k]['name'] = $the_used_good->title;
                        $orderGoods[$k]['product'] = '';
                        $orderGoods[$k]['vip_price'] = $the_used_good->price;
                        $orderGoods[$k]['price'] = $the_used_good->price;
                        $orderGoods[$k]['recharge'] = $recharge;
                        $orderGoods[$k]['quantity'] = 1;
                        $orderGoods[$k]['order_id'] = $orderId;
                        $orderGoods[$k]['seller_user_id'] = $the_used_good->user_id;
                        $orderGoods[$k]['buyer_user_id'] = $uid;
                        $orderGoods[$k]['goods_id'] = $the_used_good->id;
                        $orderGoods[$k]['goods_type'] = 6;
                        $orderGoods[$k]['product_id'] = 0;
                        $orderGoods[$k]['created_at'] = $created_at;
                        $orderGoods[$k]['refund_deadline'] = $refund_deadline;

                    }else{
                        DB::rollBack();
                        $r['code'] = 200003;
                        return $r;
                    }
                }else if($v['goods_type'] == 7){
                    $the_bureau_good = WxBureau::where('id', $v['goods_id'])->where('status', 1)->first();
                    $the_club_team = WxClubTeam::find($v['product_id']);
                    $the_bureau_group = WxBureauGroup::find($the_club_team ? $the_club_team->group_id : 0);
                    if(!_empty_($the_bureau_good) && !_empty_($the_club_team) && !_empty_($the_bureau_group)) {

                        // 临时暂用
                        if($the_bureau_good->image_urls){
                            $the_bureau_good->pic = _array_key($the_bureau_good->image_urls[0], 'url', '') . '';
                        }

                        // 允许退款的时间
                        $created_at = date('Y-m-d H:i:s', time());
                        $endDateTime = Carbon::createFromFormat('Y-m-d H:i:s', "{$the_bureau_good->service_date_end} {$the_bureau_good->service_time_end}");
                        $refund_policy = $the_bureau_good->refund_policy;
                        if($refund_policy == 255){
                            $refund_deadline = Carbon::now();
                            $created_at = $refund_deadline;
                        }else{
                            $refund_deadline = $endDateTime;
                        }


                        $recharge = $the_bureau_group->cost_per_person * 1;
                        $_order_amount += $recharge;
                        $_goods_amount += $the_bureau_group->cost_per_person * 1;
                        $orderGoods[$k]['pic'] = $the_bureau_good->pic;
                        $orderGoods[$k]['name'] = $the_bureau_good->title;
                        $orderGoods[$k]['product'] = '';
                        $orderGoods[$k]['vip_price'] = $the_bureau_group->cost_per_person;
                        $orderGoods[$k]['price'] = $the_bureau_group->cost_per_person;
                        $orderGoods[$k]['recharge'] = $recharge;
                        $orderGoods[$k]['quantity'] = 1;
                        $orderGoods[$k]['order_id'] = $orderId;
                        $orderGoods[$k]['seller_user_id'] = $the_bureau_good->user_id;
                        $orderGoods[$k]['buyer_user_id'] = $uid;
                        $orderGoods[$k]['goods_id'] = $the_bureau_good->id;
                        $orderGoods[$k]['goods_type'] = 7;
                        $orderGoods[$k]['product_id'] = $the_club_team->id;
                        $orderGoods[$k]['created_at'] = $created_at;
                        $orderGoods[$k]['refund_deadline'] = $refund_deadline;

                    } else{
                        DB::rollBack();
                        $r['code'] = 200003;
                        return $r;
                    }
                }else {
                    $the_product = WxShopGoodsProduct::where('id', $v['product_id'])->first();

                    // 规格存在并且有存量时
                    if ($the_product) {
                        $WxShopGoods = WxShopGoods::where('id', $the_product->goods_id)->first();
                        $good_servers = $WxShopGoods->service_id;
                        if (_empty_($good_servers)) {
                            $good_servers = '[]';
                        }
                        $created_at = date('Y-m-d H:i:s', time());
                        $good_servers = json_decode($good_servers, true);
                        $refund_deadline = Carbon::now()->addDays(7);
                        if (in_array(1, $good_servers)) {
                            $refund_deadline = Carbon::now();
                            $created_at = $refund_deadline;
                        }

                        $recharge = $is_vip ? $the_product->vip_price * $v['num'] : $the_product->price * $v['num'];
                        $_order_amount += $recharge;
                        $_goods_amount += $the_product->price * $v['num'];

                        $orderGoods[$k]['pic'] = $the_product->pic;
                        $orderGoods[$k]['name'] = $v['goods_name'];
                        $orderGoods[$k]['product'] = $the_product->param_value;
                        $orderGoods[$k]['vip_price'] = $the_product->vip_price;
                        $orderGoods[$k]['price'] = $the_product->price;
                        $orderGoods[$k]['recharge'] = $recharge;
                        $orderGoods[$k]['quantity'] = $v['num'];
                        $orderGoods[$k]['order_id'] = $orderId;
                        $orderGoods[$k]['seller_user_id'] = $WxShopGoods->user_id ?: 0;
                        $orderGoods[$k]['buyer_user_id'] = $uid;
                        $orderGoods[$k]['goods_id'] = $the_product->goods_id;
                        $orderGoods[$k]['goods_type'] = $WxShopGoods->type;
                        $orderGoods[$k]['product_id'] = $the_product->id;
                        $orderGoods[$k]['created_at'] = $created_at;
                        $orderGoods[$k]['refund_deadline'] = $refund_deadline;
                    } else {
                        DB::rollBack();
                        $r['code'] = 200003;
                        return $r;
                    }
                }
            }
            $ogModel = new WxShopOrderGoods();
            $ogModel->addAll($orderGoods);

            //修改购物车数据
            if(_empty_default_($request->cart_id, 0) > 0){
                WxShopCart::where('id', _empty_default_($request->cart_id, 0))->update(['state' => 2]);
            }else{
                WxShopCart::where('user_id', $uid)->where('is_check', 1)->where('state', 0)->update(['state' => 2]);
            }

            if($random_str_){
                Cache::put(md5('shop:order:random:'.$random_str_), $orderId, 60);
            }

            DB::commit();

            $r['code'] = 200;
            $r['orderSn'] = $orderSn;
            $r['order_amount'] = $order_amount;
            $r['orderId'] = $orderId;
            return $r;
        } catch (\Exception $e) {
            DB::rollBack();
            _logger_(__file__, __line__, $e->getMessage());

            $r['code'] = 200002;
            return $r;

        }

    }

    /**
     * Shop订单列表Count
     */
    public function getOrderCount(Request $request)
    {
        $uid = $request->uid;
        $seller = _empty_default_($request->seller, 0);
        return $this->success(ShopUtils::get_order_count($uid, $seller == 1));
    }

    /**
     * Shop订单列表
     */
    public function getOrderList(Request $request)
    {
        $uid = $request->uid;
        $type = $request->type;
        $seller = _empty_default_($request->seller, 0);

        $yesterday = date("Y-m-d H:i:s", strtotime("-2 hours"));
        //清除超时未支付订单
        WxShopOrder::where('user_id', $uid)->where('pay_status', 1)->where('status', 0)
            ->where('created_at', '<', $yesterday)
            ->update(['status' => 5]);

        if($seller == 1){
            if ($type == 1) {
                $data = WxShopOrder::where('seller_user_id', $uid)
                    ->where('pay_status', 1)->where('status', 0)
                    ->orderBy('created_at', 'desc')
                    ->paginate(6);
            } else if ($type == 2) {
                $data = WxShopOrder::where('seller_user_id', $uid)
                    ->where('pay_status', 2)->where('status', 1)
                    ->orderBy('created_at', 'desc')
                    ->paginate(6);
            } else if ($type == 3) {
                $data = WxShopOrder::where('seller_user_id', $uid)
                    ->where('pay_status', 2)->where('status', 2)
                    ->orderBy('created_at', 'desc')
                    ->paginate(6);
            } else if ($type == 4) {
                // 退款中

                $order_ids = WxShopOrderGoods::select('order_id')->whereIn('state', [1,2])->whereIn('order_id', function ($query) use($uid){
                    $query->select('id')->from('wx_shop_order')->where('seller_user_id', $uid)->whereIn('status', [1, 2, 7]);
                })->distinct()->pluck('order_id')->toArray();
                $data = WxShopOrder::whereIn('id', $order_ids)
                    ->orderBy('created_at', 'desc')
                    ->paginate(6);

            } else {
                if(UserUtils::is_mini_supder_admin($uid)){
                    $data = WxShopOrder::whereIn('seller_user_id', [$uid, 0])
                        ->where('status', '<>', 6)
                        ->orderBy('created_at', 'desc')
                        ->paginate(6);
                }else{
                    $data = WxShopOrder::where('seller_user_id', $uid)
                        ->where('status', '<>', 6)
                        ->orderBy('created_at', 'desc')
                        ->paginate(6);
                }
            }

            $data->map(function ($v) {
                $v->goods = WxShopOrderGoods::where('order_id', $v->id)->get();
                $has_refund_good = false;
                $face_to_face = 0;
                if($v->status == 8){
                    ShopOrderDeliverInfoManage::dispatch('query', $v->id, null);
                }else if($v->status == 10){
                    ShopOrderDeliverInfoManage::dispatch('virtual-query', $v->id, null);
                }else if($v->status == 9){
                    ShopOrderDeliverInfoManage::dispatch('virtual-upload', $v->id, null);
                }
                if($v->goods){
                    $v->goods->map(function ($good, $k) use (&$has_refund_good, &$face_to_face){
                        if($good->state == 1 || $good->state == 2){
                            $has_refund_good = true;
                        }
                        if($good->goods_type == 6){
                            if(WxUsedGood::where('id', $good->goods_id)->value('is_self_pickup') == 1){
                                $face_to_face = 1;
                            }
                        }else if($good->goods_type == 5){
                            $face_to_face = 2;
                        }else if($good->goods_type == 7){
                            $face_to_face = 3;
                        }
                        return $good;
                    });
                }
                if($face_to_face > 0){
                    $order_coupon = WxShopOrderCoupon::where('order_id', $v->id)->first();
                    if($order_coupon && $order_coupon->scanner > 0){
                        $order_coupon->scan_user = UserUtils::get_cached_user($order_coupon->scanner);
                        $v->order_coupon = $order_coupon;
                    }
                }
                // 全部退款中就是7，这个表达商品列表中是否有退款中商品
                $v->has_refund = $has_refund_good ? 1 : 0;
                // 支持面对面 0：不支持 1：二手的支持 2：核销的支持 3: 组局的核销
                $v->face_to_face = $face_to_face > 0 ? $face_to_face : 0;
                $v->status_text = self::orderStatusText($v->pay_status, $v->status);
            });

            return $this->success($data);

        }else{
            if ($type == 1) {
                $data = WxShopOrder::where('user_id', $uid)
                    ->where('pay_status', 1)->where('status', 0)
                    ->orderBy('created_at', 'desc')
                    ->paginate(6);
            } else if ($type == 2) {
                $data = WxShopOrder::where('user_id', $uid)
                    ->where('pay_status', 2)->where('status', 1)
                    ->orderBy('created_at', 'desc')
                    ->paginate(6);
            } else if ($type == 3) {
                $data = WxShopOrder::where('user_id', $uid)
                    ->where('pay_status', 2)->where('status', 2)
                    ->orderBy('created_at', 'desc')
                    ->paginate(6);
            } else if ($type == 4) {
                $data = WxShopOrder::where('user_id', $uid)
                    ->where('pay_status', 2)->where('status', 3)
                    ->orderBy('created_at', 'desc')
                    ->paginate(6);
            } else {
                $data = WxShopOrder::where('user_id', $uid)
                    ->where('status', '<>', 6)
                    ->orderBy('created_at', 'desc')
                    ->paginate(6);
            }

            $data->map(function ($v) {
                $v->goods = WxShopOrderGoods::where('order_id', $v->id)->get();
                $has_refund_good = false;
                $face_to_face = 0;
                if($v->goods){
                    $v->goods->map(function ($good, $k) use (&$has_refund_good, &$face_to_face){
                        if($good->state == 1 || $good->state == 2){
                            $has_refund_good = true;
                        }
                        if($good->goods_type == 6){
                            if(WxUsedGood::where('id', $good->goods_id)->value('is_self_pickup') == 1){
                                $face_to_face = 1;
                            }
                        }else if($good->goods_type == 5){
                            $face_to_face = 2;
                        }else if($good->goods_type == 7){
                            $face_to_face = 3;
                        }
                        return $good;
                    });
                }
                // 全部退款中就是7，这个表达商品列表中是否有退款中商品
                $v->has_refund = $has_refund_good ? 1 : 0;

                // 支持面对面 0：不支持 1：二手的支持 2：核销的支持 3：组局的核销
                $v->face_to_face = $face_to_face > 0 ? $face_to_face : 0;

                $v->status_text = self::orderStatusText($v->pay_status, $v->status);
            });

            return $this->success($data);
        }
    }

    /**
     * 订单状态
     * @param $pay_status
     * @param $status
     */
    public static function orderStatusText($pay_status, $status)
    {
        $text = '';
        if ($pay_status == 1 && $status == 0) {
            $text = '待支付（2分钟内有效）';
        } else if ($pay_status == 2 && $status == 1) {
            $text = '待发货';
        } else if ($pay_status == 2 && $status == 2) {
            $text = '待收货';
        } else if ($pay_status == 2 && $status == 3) {
            $text = '待晒单';
        } else if ($pay_status == 1 && $status == 5) {
            $text = '已取消';
        } else if ($pay_status == 3 && $status == 4) {
            $text = '已退款';
        } else if ($pay_status == 2) {
            if($status == 8){
                $text = '待收货';
            }else if($status == 9){
                $text = '待发货';
            }else if($status == 10){
                $text = '需微信收货';
            }
        }
        return $text;
    }

    /**
     * Shop删除订单
     */
    public function delOrder(Request $request)
    {
        $uid = $request->uid;
        $oid = $request->oid;

        $r = WxShopOrder::where('user_id', $uid)->where('id', $oid)->whereIn('status', [5, 4, 3])
            ->update(['status' => 6]);
        if($r){
            return $this->success();
        }
        return $this->fail(200004);
    }

    /**
     * Shop取消订单
     */
    public function cancelOrder(Request $request)
    {
        $uid = $request->uid;
        $oid = $request->oid;
        $random_str_ = _empty_default_($request->random_str_, '');
        if(_empty_($oid)){
            if(!_empty_($random_str_)){
                $oid = Cache::get(md5('shop:order:random:'.$random_str_));
            }
        }
        if(_empty_($oid)){
            return $this->fail(200001);
        }

        DB::beginTransaction();
        try {
            if(WxShopOrder::where('user_id', $uid)->where('id', $oid)->where('pay_status', 1)->where('status', 0)->exists()){
                // todo:
                WxShopOrderGoods::where('order_id', $oid)->get()->map(function ($v2){
                    // 库存返还 $rows = ->delete();
                    if($v2->goods_type == 6){
                        // 二手
                        WxUsedGood::where('id', $v2->goods_id)->where('status', 7)->update([
                            'status' => 1
                        ]);
                    }else{
                        WxShopGoodsProduct::where('id', $v2->product_id)->where('state', 0)->increment('stock', (int)($v2->quantity));
                    }
                });
                WxShopOrder::where('user_id', $uid)->where('id', $oid)->update(['status' => 5]);
                DB::commit();
                return $this->success();
            }
            DB::rollBack();
            return $this->fail(200000);
        } catch (\Exception $e) {
            DB::rollBack();
            _logger_(__file__, __line__, $e->getMessage());
            return $this->fail(200002);
        }
    }

    /**
     * Shop重新付款
     */
    public function payment(Request $request)
    {
        $uid = $request->uid;
        $openid = WxUser::where('id', $uid)->value('weixin_openid');
        $appid = Settings::get('app_id');
        $mch_id = Settings::get('mch_id');
        $key = Settings::get('mch_secret');
        $out_trade_no = $request->orderSn;
        $body = Settings::get('app_title').'SHOP购物';
        $total_fee = $request->order_amount;

        return $this->payHandler($uid, 'wxpay', 'mini', $total_fee, $body, $out_trade_no, 2);

//        $payObject = new WeixinPay($appid, $openid, $mch_id, $key, $out_trade_no, $body, $total_fee);
//        $pay_result = $payObject->pay();
//        if(_array_key($pay_result, 'return_code', '') == 'FAIL'){
//            return $this->fail(200014, [], $pay_result['return_msg']);
//        }else{
//            return $this->success($pay_result);
//        }
    }

    /**
     * App Shop重新付款
     */
    public function paymentForApp(Request $request)
    {
        if(!in_array($request->provider, ['wxpay', 'alipay'])){
            return $this->fail(200004, ['msg'=>'provider参数仅支持wxpay/alipay']);
        }

        if(!in_array($request->pay_type, ['app', 'h5', 'yi', 'code', 'code_pc'])){
            return $this->fail(200004, ['msg'=>'pay_type参数仅支持app/h5/yi/code']);
        }

        $uid = $request->uid;
        $out_trade_no = $request->orderSn;
        $total_fee = $request->order_amount;
        $body = Settings::get('app_title').'SHOP购物';

        $pay_type = $request->pay_type;
        global $__MINI_GLOBAL_DEVICE__;
        if($__MINI_GLOBAL_DEVICE__ == 'h5' && _empty_default_($request->h5_browser, '') == 'wxclient'){
            $pay_type = 'mp';
        }

        return $this->payHandler($uid, $request->provider, $pay_type, $total_fee, $body, $out_trade_no, 2);
    }

    /**
     * 查询物流
     * @param Request $request
     * @param $no 快递单号
     * @return \Illuminate\Http\JsonResponse
     */
    public function kuaidi(Request $request)
    {
        $no = $request->no;//快递单号
        $type = _empty_default_($request->type, '');

        $appcode = Settings::get('app_ali_wuliu_appcode');//换成你自己阿里云的appcode
        if(_empty_($no) || _empty_($appcode)){
            return $this->fail(200001);
        }

        $formData = ['no'=>$no];
        if(!_empty_($type)){
            $formData['type'] = $type;
            if($type == 'SFEXPRESS'){
                $adds_mobile = WxShopOrder::where('express_no', $no)->where('express_type', $type)->value('adds_mobile');
                if($adds_mobile){
                    $no .= ':'.substr($adds_mobile, -4);
                    $formData['no'] = $no;
                }
            }
        }else{
            $shop_order = WxShopOrder::where('express_no', $no)->first();
            if($shop_order){
                $express_type = $shop_order->express_type;
                $formData['type'] = $express_type;
                if($express_type == 'SFEXPRESS'){
                    $adds_mobile = $shop_order->adds_mobile;
                    if($adds_mobile){
                        $no .= ':'.substr($adds_mobile, -4);
                        $formData['no'] = $no;
                    }
                }
            }
        }



        $res = ApiUtils::ali_request($appcode, 'https://wuliu.market.alicloudapi.com/kdi', $formData);
        if($res){
            if($res && $res['status'] == 0){
                return $this->success($res['result']);
            }
        }
        if($res === null){
            UserUtils::assistant_notice('admin', '【阿里全国快递物流查询】Api不可用，是不是服务没开通');
            _logger_(__file__, __line__, '【阿里全国快递物流查询】Api不可用，是不是服务没开通');
        }
        return $this->fail(200003, [], $data['msg'] ?? '暂时未查询到该订单');

    }




    public function deliver(Request $request){
        $uid = $request->uid;
        $action = _empty_default_($request->action, 'express');
        if(!in_array($action, ['express', 'coupon'])){
            return $this->fail(200004);
        }

        $remark = _empty_default_($request->remark, '');
        if($action == 'express'){

            $order_id = _empty_default_($request->order_id, 0);
            if(_empty_($order_id)){
                return $this->fail(200001);
            }

            $WxOrder = WxShopOrder::find($order_id);
            if(!$WxOrder){
                return $this->fail(200003);
            }

            if($WxOrder->seller_user_id != $uid && !UserUtils::is_mini_supder_admin($uid)){
                return $this->fail(200000);
            }

            if($WxOrder->pay_status != 2 || $WxOrder->status != 1){
                return $this->fail(200004, [], '该订单已不是待发货状态');
            }

            $express_type = _empty_default_($request->express_type, '');
            $express_no = _empty_default_($request->express_no, '');
            if(_empty_($express_type) || _empty_($express_no)){
                return $this->fail(200001);
            }

            $express = '';
            $express_arr = ShopUtils::get_expree_name_range();
            foreach ($express_arr as $item){
                if($item['type'] == $express_type){
                    $express = $item['name'];
                    break;
                }
            }
            if(_empty_($express)){
                return $this->fail(200004, [], '未查找到该快递公司');
            }

            $remark = strip_tags($remark);
            if(_empty_($remark)){
                $remark = '';
            }

            // 验证express_no是否可用
            $flag = true;
            if(!$flag){
                $appcode = Settings::get('app_ali_wuliu_appcode');//换成你自己阿里云的appcode
                if(_empty_($appcode)){
                    return $this->fail(200001, [], '管理员未配置阿里物流查询接口');
                }

                // 顺丰特殊情况
                if(_empty_($express_type)){
                    $shop_order = WxShopOrder::where('express_no', $express_no)->first();
                    if($shop_order){
                        $express_type = $shop_order->express_type;
                        if($express_type == 'SFEXPRESS'){
                            $adds_mobile = $shop_order->adds_mobile;
                            if($adds_mobile){
                                $express_no .= ':'.substr($adds_mobile, -4);
                            }
                        }
                    }
                }else{
                    if($express_type == 'SFEXPRESS'){
                        $adds_mobile = WxShopOrder::where('express_no', $express_no)->where('express_type', $express_type)->value('adds_mobile');
                        if($adds_mobile){
                            $express_no .= ':'.substr($adds_mobile, -4);
                        }
                    }
                }

                $res = ApiUtils::ali_request($appcode, 'https://wuliu.market.alicloudapi.com/kdi', ['no'=>$express_no, 'type' => $express_type ]);
                if($res){
                    if($res && $res['status'] == 0){
                        $flag = true;
                    }else{
                        return $this->fail(200004, [], $res['msg']);
                    }
                }
                if(!$flag){
                    return $this->fail(200004, [], '未查找到物流信息');
                }
            }

            DB::beginTransaction();
            try {
                // todo:
                $ship_at = date('Y-m-d H:i:s', time());
                WxShopOrder::where('id', $order_id)->update([
                    'express' => $express,
                    'express_no' => $express_no,
                    'express_type' => $express_type,
                    'remark' => $remark,
                    'ship_at' => $ship_at,
                    'status' => 2,
                ]);

                $oinfo = WxShopOrder::where('id', $order_id)->first();

                $nr = '您的订单：' . $oinfo['order_id'] . ' 由：' . $express . '：「<a href="/pagesA/shop/logistics/logistics?nu='.$express_no.'&type='.$express_type.'">' . $express_no . '</a>」已经发出了。';
                // 发送通知
                UserUtils::add_user_notice(6001, $oinfo['user_id'], '商品发货通知', $nr, 100, '', $order_id);

                // 处理售后的催货
                WxShopOrderAfter::where([
                    ['order_id', '=', $oinfo['order_id']],
                    ['title', '=', '催发货']
                ])->update([
                    'state' => 1,
                ]);

                Cache::forget('total:todo:count');
                Cache::forget('total:tenant:todo:count');
                GatewayUtils::success(GatewayUtils::uid2client_id($uid), 17);
                GatewayUtils::success(GatewayUtils::uid2client_id($WxOrder->user_id), 17);
                GatewayUtils::success(GatewayUtils::uid2client_id($WxOrder->user_id), 12);

                DB::commit();
                return $this->success([
                    'express_no' => $express_no,
                    'express_type' => $express_type,
                ]);
            } catch (\Exception $e) {
                DB::rollBack();
                _logger_(__file__, __line__, $e->getMessage());
                return $this->fail(200006);
            }

        }else if($action == 'coupon'){
            $code = _empty_default_($request->code, '');
            $code = str_replace(' ', '', $code);
            if(_empty_($code)){
                return $this->fail(200001);
            }

            $coupon = WxShopOrderCoupon::where('code', $code)->first();
            if(!$coupon){
                return $this->fail(200003);
            }

            if($coupon->status !== 0){
                return $this->fail(200010, [], '该扫码卷已不可使用');
            }


            $order_id = $coupon->order_id;

            $WxOrder = WxShopOrder::find($order_id);
            if(!$WxOrder){
                return $this->fail(200003);
            }

            if($WxOrder->pay_status != 2 || $WxOrder->status != 1){
                return $this->fail(200004, [], '订单不是已支付和待发货状态');
            }

            $order_goods = WxShopOrderGoods::where('order_id', $WxOrder->id)->where('state', 0)->get()->toArray();
            if(_empty_($order_goods)){
                return $this->fail(200010, [], '参数错误');
            }

            $scanners = [];
            if($WxOrder->order_from === 0){
                $goods_id = $order_goods[0]['goods_id'];
                $scanners = WxShopGoods::where('id', $goods_id)->value('scanners');
                $is_in_scanners = false;

                if($scanners){
                    if(is_string($scanners)){
                        $scanners = explode(',', $scanners);
                    }
                }
            }else if($WxOrder->order_from == 7){
                $the_order_good = $order_goods[0];
                $the_bureau = WxBureau::find(_array_key($the_order_good, 'goods_id', 0));
                if($the_bureau){
                    $club = WxClub::find($the_bureau->club_id);
                    if($club){
                        $scanners = _empty_default_(json_decode(_empty_default_($club->assistants, '[]'), true), []);
                    }
                }
            }

            if(_empty_($scanners)){
                $scanners = [];
            }
            if(in_array($uid, $scanners)){
                $is_in_scanners = true;
            }

            if($WxOrder->seller_user_id != $uid && !UserUtils::is_mini_supder_admin($uid) && !$is_in_scanners){
                return $this->fail(200000, [], '您不是该订单的核销人');
            }

            if($WxOrder->pay_status != 2 || $WxOrder->status != 1){
                return $this->fail(200004, [], '该订单已不是待发货状态');
            }

            $shopOrder = WxShopOrder::where('id', $order_id)->first();
            // 先检查是否需要对接发货信息管理
            $is_need_deliver_info_manage = false;
            if($shopOrder->serial_platform === 0 && $shopOrder->serial_platform_type == 'mini' && Settings::get('need_mini_deliver_info_manage', 0) == 1){
                $is_need_deliver_info_manage = true;
            }
            if($is_need_deliver_info_manage){
                $weapp = new WeApp('mini');
                $manage = $weapp->getDeliverInfoManage();
                $manage->selfPickUp($WxOrder, $uid);
                return $this->fail(200047, [ 'query_state_no' => ('wx_shoporder_' . $shopOrder->serial_number) ]);
            }else{
                if(ShopUtils::coupon_to_finish($shopOrder, $uid, '')){
                    GatewayUtils::success(GatewayUtils::uid2client_id($uid), 17);
                    GatewayUtils::success(GatewayUtils::uid2client_id($WxOrder->user_id), 17);
                    return $this->success();
                }else{
                    return $this->fail(200006);
                }
            }
        }

    }

    /**
     * Shop催发货
     */
    public function pushDelivery(Request $request)
    {
        $uid = $request->uid;
        // 长id
        $on = $request->on;
        $title = $request->title;
        $message = $request->message;

        $used_goods_id = [];
        // 自营
        $system_shop_goods_id = [];
        // 短id
        $wxShopOrder = WxShopOrder::where('order_id', $on)->first();
        if(_empty_($wxShopOrder)){
            return $this->fail(200003);
        }
        $the_order_id = $wxShopOrder->id;
        WxShopOrderGoods::where('order_id', $the_order_id)->get()->map(function ($v) use (&$used_goods_id, &$system_shop_goods_id){
            if($v->goods_type == 6){
                $used_goods_id[] = $v->goods_id;
            }else{
                $system_shop_goods_id[] = $v->goods_id;
            }
        });


        if($used_goods_id){
            foreach ($used_goods_id as $used_id){
                $WxUsedGood = WxUsedGood::find($used_id);
                $user_id = $WxUsedGood->user_id;
                UserUtils::assistant_notice($user_id, '您的闲置商品(<a href="/pagesU/used-mall/detail/index?id='.$WxUsedGood->id.'">id: '.$WxUsedGood->id.'</a>)订单被催发货了，请您和购买者协商，达成一致的发货的时间约定');
            }
            return $this->success();
        }


        if($system_shop_goods_id){
            $isExists = WxShopOrderAfter::where('user_id', $uid)->where('order_id', $on)->where('state', 0)->exists();
            if ($isExists) {
                return $this->fail(800010);
            } else {
                $model = new WxShopOrderAfter();
                $model->user_id = $uid;
                $model->seller_user_id = $wxShopOrder->user_id;
                $model->order_id = $on;
                $model->title = $title;
                $model->content = $message;
                $model->save();
                return $this->success();
            }
        }
    }

    /** 扫码劵
     * @param Request $request
     */
    public function orderCoupon(Request $request){
        $uid = $request->uid;
        $action = _empty_default_($request->action, 'get');
        if(!in_array($action, ['get'])){
            return $this->fail(200001);
        }

        $order_id = _empty_default_($request->order_id, 0);
        if(_empty_($order_id)){
            return $this->fail(200001);
        }

        $order = WxShopOrder::where([
            ['id', '=', $order_id],
            ['user_id', '=', $uid],
            ['pay_status', '=', 2],
//            ['status', '=', 1]
        ])->first();

        if(!$order){
            return $this->fail(200004, [], '当前订单不是已支付状态，无法获得扫码卷');
        }

        if($action == 'get'){
            $coupon = ShopUtils::get_user_coupon($uid, $order_id);
            $goods = WxShopOrderGoods::where('order_id', $order_id)->get();
            $order_title = '';
            $order_image = '';
            $is_used = false;
            if($goods){
                $goods->map(function ($v, $k) use (&$order_title, &$order_image, &$is_used, &$order){
                    if(!_empty_($order_title)){
                        $order_title .= '、';
                    }
                    $order_title .= $v->name;
                    if(_empty_($order_image)){
                        $order_image = $v->pic;
                    }
                    if($v->goods_type == 6){
                        $is_used = true;

                        $user_good = WxUsedGood::find($v->goods_id);
                        if($user_good->distance && $user_good->distance > 0){
                            if($user_good->distance < 10){
                                $user_good->distance = '<10m';
                                $user_good->distance_name = $user_good->district;
                            }else if($user_good->distance >= 1000 && $user_good->distance <= 200000){
                                $user_good->distance = '<'. round($user_good->distance / 1000, 2).'km';
                                $user_good->distance_name = $user_good->city;
                            }else if($user_good->distance > 200000){
                                $user_good->distance = round($user_good->distance / 1000, 2).'km';
                                $user_good->distance_name = $user_good->province;
                            }else{
                                $user_good->distance = '<'.(int)$user_good->distance.'m';
                                $user_good->distance_name = $user_good->district;
                            }
                        }else{
                            $user_good->distance = '';
                            $user_good->distance_name = $user_good->district;
                        }
                        if(_empty_($user_good->distance_name)){
                            $user_good->distance_name = '';
                        }

                        $order->distance = $user_good->distance;
                        $order->longitude = $user_good->longitude;
                        $order->latitude = $user_good->latitude;
                        $order->address_name = $user_good->address_name;
                        $order->address_detailed = $user_good->address_detailed;
                    }else if($v->goods_type == 5 || $v->goods_type == 7){
                        $shop_contact = WxShopContact::find($order->contact_id);
                        if(!$shop_contact){
                            _logger_(__file__, __line__, 'shop_contact id为'.$order->contact_id.'不存在');
                        }
                        $order->distance = '';
                        $order->longitude = $shop_contact->longitude;
                        $order->latitude = $shop_contact->latitude;
                        $order->address_name = $shop_contact->address_name;
                        $order->address_detailed = $shop_contact->address_detail;
                        if($shop_contact->phone){
                            $order->seller_phone = $shop_contact->phone;
                        }
                    }
//                    状态(0正常，1退款中，2退货退款，3已退款，4异常)
                    if($v->state == 1){
                        $v->state_tip = '退款中';
                    }else if($v->state == 2){
                        $v->state_tip = '退货退款';
                    }else if($v->state == 3){
                        $v->state_tip = '已退款';
                    } else if($v->state == 4){
                        $v->state_tip = '异常';
                    } else if($v->state == 5){
                        $v->state_tip = '微信退款处理中';
                    } else if($v->state == 6){
                        $v->state_tip = '支付宝退款处理中';
                    }else{
                        if($v->refund_deadline === 0){
                            $v->state_tip = '不支持退款';
                        }else if($v->refund_deadline == 1){
                            $v->state_tip = '申请退款';
                        }else{
                            $v->state_tip = '超时不可退款';
                        }
                    }
                });
            }
            $order->address_tip = ($order->distance ? ('距您'.$order->distance. ' · ') : '') . $order->address_name;
            $order->order_title = $order_title;
            $order->order_image = $order_image;
            $order->is_used = $is_used;
            if(_empty_($order->seller_phone)){
                $order->seller_phone = $order->seller_user_id > 0 ? _get_origin_attribute('wx_user', [['id', '=', $order->seller_user_id]], 'phone') : '';
            }
            $order->query_state_no = 'wx_shoporder_' . $order->serial_number;
            return $this->success([
                'order' => $order,
                'coupon' => $coupon,
                'goods' => $goods
            ]);
        }
    }

    /**
     * Shop申请退款
     */
    public function orderRefund(Request $request)
    {
        $uid = $request->uid;
        $action = _empty_default_($request->action, 'add');
        // todo: 这是订单的某个规格的退款， 还有一种情况是整个订单的退款

        if($action == 'add'){
            // 申请退款

            // 1、根据某个订单的product_id做定位
            $oid = $request->oid;
            $opid = $request->opid;

            // 2、直接根据orderGood id做定位
            $order_good_id = $request->order_good_id;

            if($order_good_id > 0){
                $oginfo = WxShopOrderGoods::where('buyer_user_id', $uid)->where('id', $order_good_id)->first();
            }else{
                $oginfo = WxShopOrderGoods::where('buyer_user_id', $uid)->where('order_id', $oid)->where('product_id', $opid)->first();
            }

            if(_empty_($oginfo)){
                return $this->fail(200003);
            }
            if($oginfo->refund_deadline == 0){
                return $this->fail(200009, [], '该商品不支持退款');
            }

            if($oginfo->refund_deadline == 2){
                return $this->fail(200009, [], '您已超过最大可退款期限');
            }

            $shopOrder = WxShopOrder::where('id', $oginfo['order_id'])->first();
            if(_empty_($shopOrder)){
                return $this->fail(200003);
            }
            $title = '退款申请';
            $message = '订单：'.$shopOrder['order_id'].'：'.$oginfo['quantity'].'件 '.$oginfo['name'].'【'.$oginfo['product'].'】会员价为：【'.$oginfo['vip_price'].'】普通价为：'.$oginfo['price'].' 申请退款。';

            if( $oginfo->goods_type != 2 && $oginfo->goods_type != 3 ){
                DB::beginTransaction();
                try {
                    // todo:
                    WxShopOrderGoods::where('order_id', $oid)->where('product_id', $opid)
                        ->update(['state' => 1]);

                    $model = new WxShopOrderAfter();
                    $model->user_id = $uid;
                    $model->seller_user_id = $oginfo->seller_user_id ?: 0;
                    $model->order_id = $shopOrder['order_id'];
                    $model->title = $title;
                    $model->content = $message;
                    $model->save();

                    $order_id = $oginfo->order_id;
                    if(!WxShopOrderGoods::where('order_id', $order_id)->where('state', 0)->exists()){
                        update_shop_order_meta($order_id, 'last_status', WxShopOrder::where('id', $order_id)->value('status'), 'n');
                        WxShopOrder::where('id', $order_id)->update([
                            'status' => 7
                        ]);
                    }

                    if($oginfo->goods_type == 7){
                        // 自动退款之前先检查订单状态
                        if($shopOrder->pay_status != 2 || !in_array($shopOrder->status, [0, 1])){
                            DB::rollBack();
                            return $this->fail(200006);
                        }
                        // 组局的自动退款
                        $the_bureau_good = WxBureau::where('id', $oginfo->goods_id)->first();
                        if($the_bureau_good){
                            $startDateTime = Carbon::createFromFormat('Y-m-d H:i:s', "{$the_bureau_good->service_date_start} {$the_bureau_good->service_time_start}");
                            $refund_policy = $the_bureau_good->refund_policy;
                            $nHoursAgo = Carbon::now()->subHours($refund_policy);
                            if ($startDateTime->greaterThan($nHoursAgo)) {
                                // 启动自动退
                                $r = ShopUtils::order_good_refund($oginfo->id);
                                DB::commit();
                                return $this->success([], 201, '按照活动退款政策，已为您自动退款');
                            }
                        }
                    }

                    DB::commit();
                    return $this->success([], 200, '退款申请提交成功，我们会尽快为您处理。');
                } catch (\Exception $e) {
                    DB::rollBack();
                    _logger_(__file__, __line__, $e->getMessage());
                    return $this->fail(200006);
                }
            }
            return $this->fail(200004, [], '虚拟物品不能申请退款');
        }else if($action == 'confirm' || $action == 'cancel'){
            // 同意退款
            $order_good_id = _empty_default_($request->order_good_id, 0);
            if(_empty_($order_good_id)){
                return $this->fail(200001);
            }
            $orderGood = WxShopOrderGoods::find($order_good_id);
            if(_empty_($orderGood)){
                return $this->fail(200003);
            }
            $old_state = $orderGood->state;
            if($old_state != 1 && $old_state != 2){
                return $this->fail(200004, [], '该订单商品状态不是退款中');
            }
            $order_id = $orderGood->order_id;
            $seller_user_id = WxShopOrder::where('id', $order_id)->value('seller_user_id');
            if(_empty_($seller_user_id)){
                return $this->fail(200000);
            }

            if($seller_user_id != $uid){
                return $this->fail(200000, [], '你不是该次订单的卖家');
            }

            if($action == 'confirm'){
                $r = ShopUtils::order_good_refund($order_good_id);
                if($r){
                    return $this->success();
                }else{
                    return $this->fail(200006);
                }
            }else{
                DB::beginTransaction();
                try {
                    // todo:
                    if($old_state != 3){
                        // 这里仅仅再判断一次，已无必要
                        WxShopOrderGoods::where('id', $order_good_id)->update([
                            'state' => 0,
                        ]);
                        $last_status = get_shop_order_meta($order_id, 'last_status', 'n');
                        if(_empty_($last_status, true)){
                            $last_status = 1;
                        }
                        update_shop_order_meta($order_id, 'last_status', null, 'n');
                        WxShopOrder::where('id', $order_id)->update(['status' => $last_status]);
                        DB::commit();
                        return $this->success();
                    }
                    DB::rollBack();
                    return $this->fail(200006);
                } catch (\Exception $e) {
                    DB::rollBack();
                    _logger_(__file__, __line__, $e->getMessage());
                    return $this->fail(200006);
                }

            }
        }
    }

    /**
     * Shop退货退款
     */
    public function refundGoods(Request $request)
    {
        $uid = $request->uid;
        $on = $request->on;
        $oid = $request->oid;
        $opid = $request->opid;
        $title = $request->title;
        $message = $request->message;
        $oginfo = WxShopOrderGoods::where('order_id', $oid)->where('product_id', $opid)->first();
        if(_empty_($oginfo)){
            return $this->fail(200003);
        }
        if($oginfo->refund_deadline == 0){
            return $this->fail(200009, [], '该商品不支持退款');
        }

        if($oginfo->refund_deadline == 2){
            return $this->fail(200009, [], '您已超过最大可退款期限');
        }

        if( $oginfo->goods_type != 2 && $oginfo->goods_type != 3 ){

            WxShopOrderGoods::where('order_id', $oid)->where('product_id', $opid)
                ->update(['state' => 2]);

            $model = new WxShopOrderAfter();
            $model->user_id = $uid;
            $model->seller_user_id = $oginfo->seller_user_id ?: 0;
            $model->order_id = $on;
            $model->title = $title;
            $model->content = $message;
            $model->save();


            $nr = '您购买的：「' . $oginfo['name'] . '(规格：' . $oginfo['product'] . ')」×' . $oginfo['quantity'] . '件的售后申请已提交，您需要联系客服将货物退回。';
            UserUtils::add_user_notice(6002, $uid, '商品售后通知', $nr, 100);

            return $this->success();
        }
        return $this->fail(200004, [], '虚拟物品不能申请退货退款');
    }

    public function shop_order_process(Request $request) {
        $type = _empty_default_($request->type, '');
        if ($type == 'update_user_remark') {
            return $this->user_remark($request);
        }
    }

    private function user_remark(Request &$request){
        $uid = $request->uid;
        $order_id = _empty_default_($request->order_id, 0);
        $user_remark = _empty_default_($request->user_remark, '');
        if(_empty_($order_id) || _empty_($user_remark)){
            return $this->fail(200001);
        }
        if(is_array($user_remark)){
            $user_remark = json_encode($user_remark);
        }
        $shop_order = WxShopOrder::find($order_id);
        if(!$shop_order){
            return $this->fail(200003);
        }
        if($shop_order->status != 1){
            return $this->fail(200004, [], '当前订单状态不支持修改');
        }
        if($shop_order->user_id != $uid && !UserUtils::is_mini_supder_admin($uid)){
            return $this->fail(200004, [], '当前订单不是你的订单，无法修改');
        }
        WxShopOrder::where('id', $order_id)->where('user_id', $uid)->update([
            'user_remark' => $user_remark
        ]);
        return $this->success();
    }

    /**
     * Shop确认收货
     */
    public function confirmReceipt(Request $request)
    {
        $uid = $request->uid;
        $oid = $request->oid;

        if(_empty_($uid) || _empty_($oid)){
            return $this->fail(200001);
        }
        $shop_order = WxShopOrder::where([
            ['id', '=', $oid],
            ['user_id', '=', $uid],
            ['status', '=', 2],
            ['pay_status', '=', 2]
        ])->first();

        if($shop_order){
            if(ShopUtils::confirm_recived($shop_order, 1)){
                return $this->success();
            }else{
                return $this->fail(200006);
            }
        }else{
            return $this->fail(200003);
        }

    }


}
